﻿using Microsoft.Extensions.Caching.Distributed;
using My.RedisUtils;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Tingjian.gas.service.Consts;
using Tingjian.gas.service.Entities.Product;
using Tingjian.gas.service.Product.CreateDto;
using Tingjian.gas.service.Product.GetDto;
using Tingjian.gas.service.Product.UpdateDto;
using Tingjian.gas.service.Utility.CommonUtility;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;

namespace Tingjian.gas.service.Product
{
    public class ProductAppService : ApplicationService, IProductAppService
    {
        private readonly IGasMeterRepository _gasMeterRepository;
        private readonly IServiceProvider _serviceProvider;

        public ProductAppService(IGasMeterRepository gasMeterRepository,
            IServiceProvider serviceProvider
            )
        {
            _gasMeterRepository = gasMeterRepository;
            _serviceProvider = serviceProvider;
        }

        #region redis db

        /// <summary>
        /// 插入redis list 队列
        /// </summary>
        /// <returns></returns>
        public async Task<bool> AddListInRedsi(CreateGasMeterDto input)
        {
            await Task.Delay(100);
            var redisService = _serviceProvider.GetService(typeof(IDistributedCache)) as MyRedis; //可以获取到实例
            await redisService.LPushListAsync("mylist", Newtonsoft.Json.JsonConvert.SerializeObject(input));

            return true;
        }


        /// <summary>
        /// 消费者 redis list
        /// </summary>
        /// <returns></returns>

        public async Task<bool> ConsumerRedisListAsync()
        {
            var redisService = _serviceProvider.GetService(typeof(IDistributedCache)) as MyRedis;
            var dtoPop = (await redisService.RPopListAsync("mylist")).ToString();
            var dto = JsonConvert.DeserializeObject<CreateGasMeterDto>(dtoPop ?? "");

            if (dto == null)
            {
                return false;
            }

            var listCount = await redisService.ListLengthAsync("mylist");

            Console.WriteLine($"list count {listCount}");

            if (listCount > 0)
            {
                var result = await CreateAsync(dto);
                if (result > 0)
                {
                    Console.WriteLine($"insert mysql db successly, new id {result}");
                }
            }

            return true;
        }

        #endregion

        #region mysql db

        public async Task<long> CreateAsync(CreateGasMeterDto input)
        {
            var gasMeter = ObjectMapper.Map(input, new GasMeter());
            gasMeter.CreatorId = "admin";

            await _gasMeterRepository.InsertAsync(gasMeter);

            return gasMeter.Id;
        }

        public async Task<bool> DeleteAsync(long id)
        {
            var model = await _gasMeterRepository.FindAsync(x => x.Id == id);

            if (model == null)
            {
                throw new UserFriendlyException($"商品不存在！");
            }

            await _gasMeterRepository.DeleteAsync(model);
            return true;

        }


        public async Task<long> UpdateAsync(long id, UpdateGasMeterDto input)
        {
            var model = await _gasMeterRepository.FindAsync(x => x.Id == id);

            if (model == null)
            {
                throw new UserFriendlyException($"商品不存在！");
            }

            ObjectMapper.Map(input, model);

            await _gasMeterRepository.UpdateAsync(model);
            return model.Id;

        }


        public async Task<PagedResultDto<GetGasMeterDto>> GetListPagedAsync(GetListQueryDto input)
        {
            PagedResultDto<GetGasMeterDto> listRes = new PagedResultDto<GetGasMeterDto>();

            if (input == null)
                input = new GetListQueryDto();

            var gasMeterQueryable = (await _gasMeterRepository.GetQueryableAsync());


            var query = gasMeterQueryable.WhereIf(input.Type.HasValue(), c => c.Type == input.Type)
                .WhereIf(input.GasMeterId.HasValue(), c => c.GasMeterId == input.GasMeterId)
                .WhereIf(input.CreationTimeStart.HasValue(), c => c.CreationTime > input.CreationTimeStart)
                .WhereIf(input.CreationTimeEnd.HasValue, c => c.CreationTime < input.CreationTimeEnd);

            var pagequery = query.OrderByDescending(x => x.CreationTime)
                .Select(x => new GetGasMeterDto
                {
                    Id = x.Id,
                    GasMeterId = x.GasMeterId,
                    Type = x.Type,
                    Humidity = x.Humidity,
                    Temperature = x.Temperature,
                    CreationTime = x.CreationTime
                });

            var items = await AsyncExecuter.ToListAsync(
                pagequery.PageBy((input.PageIndex - 1) * input.PageSize, input.PageSize)
            );

            var totalCount = await AsyncExecuter.CountAsync(query);

            listRes.Items = items;
            listRes.TotalCount = totalCount;

            return listRes;

        }

        public async Task<GetGasMeterDto> GetAsync(long id)
        {
            var model = await _gasMeterRepository.FindAsync(x => x.Id == id);
            if (model == null)
                return null;

            var result = ObjectMapper.Map(model, new GetGasMeterDto());
            return result;

        }


        #endregion

    }
}
